package com.invengo.base.excel;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;
import android.widget.EditText;
import android.widget.Switch;

import com.afollestad.materialdialogs.MaterialDialog;
import com.blankj.utilcode.util.TimeUtils;
import com.invengo.base.R;
import com.invengo.library_db.entity.module_check.BookBean;
import com.invengo.library_db.entity.module_check.ShelfBean;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import java8.util.stream.StreamSupport;
import me.goldze.mvvmhabit.http.interceptor.logging.LocalLogUtil;
import me.goldze.mvvmhabit.utils.constant.Constants;

public class ExportExcelUtils {
    private static String NOW_DATE = TimeUtils.getNowString(new SimpleDateFormat("yyyy-MM-dd"));

    public static final String Suffix = ".xls";

    private ExportExcelUtils() {
    }

    private static ExportExcelUtils instance;


    public static ExportExcelUtils getInstance() {
        if (instance == null) {
            synchronized (ExportExcelUtils.class) {
                if (instance == null) {
                    instance = new ExportExcelUtils();
                }
            }
        }
        return instance;
    }


    private MaterialDialog exportDialog;
    private EditText name;
    private Switch useDefault;
    private String tempName;
    private String defaultName;

    private void initDialog(Activity activity) {
        exportDialog = new MaterialDialog.Builder(activity)
                .customView(R.layout.dialog_export_excel, false)
                .positiveText("确定")
                .build();
        name = (EditText) exportDialog.findViewById(R.id.fileName);
        useDefault = (Switch) exportDialog.findViewById(R.id.useDefault);
        useDefault.setOnCheckedChangeListener((buttonView, isChecked) -> {
            name.setEnabled(!isChecked);
            if (isChecked) {
                tempName = name.getText().toString();
            }
            name.setText(isChecked ? defaultName : tempName);
        });
    }

    public void exportOfflineCollect(Activity activity, List<BookBean> bookBeans) {
        initDialog(activity);
        defaultName = "离线采集";
        name.setText("");
        useDefault.setChecked(false);
        exportDialog.getBuilder().onPositive((dialog, which) -> {
            String dirPath = Constants.EXPORT.EXPORT_PATH + File.separator + NOW_DATE;
            LocalLogUtil.newDir(dirPath);
            String path = dirPath + File.separator +
                    (TextUtils.isEmpty(name.getText()) ? defaultName : name.getText())
                    + "_" + TimeUtils.getNowString(new SimpleDateFormat("HH-mm-ss")) + Suffix;
            writeOfflineCollection2Excel(dialog.getContext(), bookBeans, path, Constants.EXPORT.EXPORT_OFFLINE_COLLECTION_BOOK);
            dialog.dismiss();
        }).build().show();
    }

    public void exportUnfindCollect(Activity activity, List<BookBean> bookBeans) {
        initDialog(activity);
        defaultName = "图书查找";
        name.setText("");
        useDefault.setChecked(false);
        exportDialog.getBuilder().onPositive((dialog, which) -> {
            String dirPath = Constants.EXPORT.EXPORT_PATH + File.separator + NOW_DATE;
            LocalLogUtil.newDir(dirPath);
            String path = dirPath + File.separator +
                    (TextUtils.isEmpty(name.getText()) ? defaultName : name.getText())
                    + "_" + TimeUtils.getNowString(new SimpleDateFormat("HH-mm-ss")) + Suffix;
            write2excelSearch(dialog.getContext(), bookBeans, path, Constants.EXPORT.EXPORT_TITLE_BOOK);
            dialog.dismiss();
        }).build().show();
    }

    private void write2excelSearch(Context context, List<BookBean> bookBeans, String filePath, String[] title) {
        ExcelUtils.initExcel(filePath, "data", title);
        List<List<String>> collect = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            collect = bookBeans.parallelStream().map((Function<BookBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getBarCode() + "");
                strings.add(bean.getBookName() + "");
                strings.add(bean.getCallNo() + "");
                strings.add(bean.getShelfCode() + "");
                strings.add(bean.getShelfName() + "");
                strings.add(bean.getRemark() + "");
                return strings;
            }).collect(Collectors.toList());
        } else {
            collect = StreamSupport.parallelStream(bookBeans)
                    .map((java8.util.function.Function<BookBean, List<String>>) bean -> {
                        ArrayList<String> strings = new ArrayList<>();
                        strings.add(bean.getTid() + "");
                        strings.add(bean.getBarCode() + "");
                        strings.add(bean.getBookName() + "");
                        strings.add(bean.getCallNo() + "");
                        strings.add(bean.getShelfCode() + "");
                        strings.add(bean.getShelfName() + "");
                        strings.add(bean.getRemark() + "");
                        return strings;
                    }).collect(java8.util.stream.Collectors.toList());
        }
        ExcelUtils.writeObjListToExcel(collect, filePath, context);
    }

    public void exportBookBeans(Activity activity, List<BookBean> bookBeans, String fileName) {
        initDialog(activity);
        defaultName = fileName;
        name.setText("");
        useDefault.setChecked(false);
        exportDialog.getBuilder().onPositive((dialog, which) -> {
            String dirPath = Constants.EXPORT.EXPORT_PATH + File.separator + NOW_DATE;
            LocalLogUtil.newDir(dirPath);
            String path = dirPath + File.separator +
                    (TextUtils.isEmpty(name.getText()) ? defaultName : name.getText())
                    + "_" + TimeUtils.getNowString(new SimpleDateFormat("HH-mm-ss")) + Suffix;
            writeBook2Excel(dialog.getContext(), bookBeans, path, Constants.EXPORT.EXPORT_TITLE_BOOK);
            dialog.dismiss();
        }).build().show();
    }

    public void exportShelfBeans(Activity activity, Map<String, List<BookBean>> shelfWithBooks, String fileName) {
        initDialog(activity);
        defaultName = fileName;
        name.setText("");
        useDefault.setChecked(false);
        exportDialog.getBuilder().onPositive((dialog, which) -> {
            String dirPath = Constants.EXPORT.EXPORT_PATH + File.separator + NOW_DATE;
            LocalLogUtil.newDir(dirPath);
            String path = dirPath + File.separator +
                    (TextUtils.isEmpty(name.getText()) ? defaultName : name.getText())
                    + "_" + TimeUtils.getNowString(new SimpleDateFormat("HH-mm-ss")) + Suffix;
            writeShelfBooks2Excel(dialog.getContext(), shelfWithBooks, path, Constants.EXPORT.EXPORT_TITLE_BOOK);
            dialog.dismiss();
        }).build().show();
    }

    public void exportShelfBeans(Activity activity, List<ShelfBean> shelfBeans, String fileName) {
        initDialog(activity);
        defaultName = fileName;
        name.setText("");
        useDefault.setChecked(false);
        exportDialog.getBuilder().onPositive((dialog, which) -> {
            String dirPath = Constants.EXPORT.EXPORT_PATH + File.separator + NOW_DATE;
            LocalLogUtil.newDir(dirPath);
            String path = dirPath + File.separator +
                    name.getText()
                    + "_" + TimeUtils.getNowString(new SimpleDateFormat("HH-mm-ss")) + Suffix;
            writeShelf2Excel(dialog.getContext(), shelfBeans, path, Constants.EXPORT.EXPORT_TITLE_BOOK);
            dialog.dismiss();
        }).build().show();
    }


    public void exportListingGuide(Activity activity, List<BookBean> bookBeans) {
        initDialog(activity);
        defaultName = "上架指导";
        name.setText("");
        useDefault.setChecked(false);
        exportDialog.getBuilder().onPositive((dialog, which) -> {
            String dirPath = Constants.EXPORT.EXPORT_PATH + File.separator + NOW_DATE;
            LocalLogUtil.newDir(dirPath);
            String path = dirPath + File.separator +
                    name.getText()
                    + "_" + TimeUtils.getNowString(new SimpleDateFormat("HH-mm-ss")) + Suffix;
            write2Excel(dialog.getContext(), bookBeans, path, Constants.EXPORT.EXPORT_TITLE_BOOK);
            dialog.dismiss();
        }).build().show();
    }

    public void exportFindError(Activity activity, List<BookBean> bookBeans) {
        initDialog(activity);
        defaultName = "异常排查";
        name.setText("");
        useDefault.setChecked(false);
        exportDialog.getBuilder().onPositive((dialog, which) -> {
            String dirPath = Constants.EXPORT.EXPORT_PATH + File.separator + NOW_DATE;
            LocalLogUtil.newDir(dirPath);
            String path = dirPath + File.separator +
                    name.getText()
                    + "_" + TimeUtils.getNowString(new SimpleDateFormat("HH-mm-ss")) + Suffix;
            write2Excel(dialog.getContext(), bookBeans, path, Constants.EXPORT.EXPORT_TITLE_BOOK);
            dialog.dismiss();
        }).build().show();
    }

    private void writeOfflineCollection2Excel(Context context, List<BookBean> bookBeans, String filePath, String[] title) {
        ExcelUtils.initExcel(filePath, "data", title);
        List<List<String>> collect = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            collect = bookBeans.parallelStream().map((Function<BookBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getEpc() + "");
                strings.add(bean.getBarCode() + "");
                return strings;
            }).collect(Collectors.toList());
        } else {
            collect = StreamSupport.parallelStream(bookBeans).map((java8.util.function.Function<BookBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getEpc() + "");
                strings.add(bean.getBarCode() + "");
                return strings;
            }).collect(java8.util.stream.Collectors.toList());
        }
        ExcelUtils.writeObjListToExcel(collect, filePath, context);
    }

    private void write2Excel(Context context, List<BookBean> bookBeans, String filePath, String[] title) {
        ExcelUtils.initExcel(filePath, "data", title);
        List<List<String>> collect = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            collect = bookBeans.parallelStream().map((Function<BookBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getBarCode() + "");
                strings.add(bean.getBookName() + "");
                strings.add(bean.getCallNo() + "");
                strings.add(bean.getShelfCode() + "");
                strings.add(bean.getShelfName() + "");
                return strings;
            }).collect(Collectors.toList());
        } else {
            collect = StreamSupport.parallelStream(bookBeans).map((java8.util.function.Function<BookBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getBarCode() + "");
                strings.add(bean.getBookName() + "");
                strings.add(bean.getCallNo() + "");
                strings.add(bean.getShelfCode() + "");
                strings.add(bean.getShelfName() + "");
                return strings;
            }).collect(java8.util.stream.Collectors.toList());
        }
        ExcelUtils.writeObjListToExcel(collect, filePath, context);
    }

    private void writeBook2Excel(Context context, List<BookBean> bookBeans, String filePath, String[] title) {
        ExcelUtils.initExcel(filePath, "data", title);
        List<List<String>> collect = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            collect = bookBeans.parallelStream().map((Function<BookBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getBarCode() + "");
                strings.add(bean.getBookName() + "");
                strings.add(bean.getCallNo() + "");
                strings.add(bean.getShelfCode() + "");
                strings.add(bean.getShelfName() + "");
                strings.add(bean.getTip() + "");
                return strings;
            }).collect(Collectors.toList());
        } else {
            collect = StreamSupport.parallelStream(bookBeans).map((java8.util.function.Function<BookBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getBarCode() + "");
                strings.add(bean.getBookName() + "");
                strings.add(bean.getCallNo() + "");
                strings.add(bean.getShelfCode() + "");
                strings.add(bean.getShelfName() + "");
                strings.add(bean.getTip() + "");
                return strings;
            }).collect(java8.util.stream.Collectors.toList());
        }
        ExcelUtils.writeObjListToExcel(collect, filePath, context);
    }

    private void writeShelf2Excel(Context context, List<ShelfBean> shelfBeans, String filePath, String[] title) {
        ExcelUtils.initExcel(filePath, "data", title);
        List<List<String>> collect = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
            collect = shelfBeans.parallelStream().map((Function<ShelfBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getShelfCode() + "");
                strings.add(bean.getShelfName() + "");
                strings.add(bean.getFirstBookName() + "");//首书名
                strings.add(bean.getFirstBookID() + "");//条码号
                strings.add(bean.getBookIndex() + "");//索书号
                return strings;
            }).collect(Collectors.toList());
        } else {
            collect = StreamSupport.parallelStream(shelfBeans).map((java8.util.function.Function<ShelfBean, List<String>>) bean -> {
                ArrayList<String> strings = new ArrayList<>();
                strings.add(bean.getTid() + "");
                strings.add(bean.getShelfCode() + "");
                strings.add(bean.getShelfName() + "");
                strings.add(bean.getFirstBookName() + "");//首书名
                strings.add(bean.getFirstBookID() + "");//条码号
                strings.add(bean.getBookIndex() + "");//索书号
                return strings;
            }).collect(java8.util.stream.Collectors.toList());
        }
        ExcelUtils.writeObjListToExcel(collect, filePath, context);
    }

    private void writeShelfBooks2Excel(Context context, Map<String, List<BookBean>> shelfWithBooks, String filePath, String[] title) {
        for (String key : shelfWithBooks.keySet()) {
            ExcelUtils.initExcel(filePath, "data", title);
            List<List<String>> collect = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                collect = shelfWithBooks.get(key).stream().map((Function<BookBean, List<String>>) bean -> {
                    ArrayList<String> strings = new ArrayList<>();
                    strings.add(bean.getTid() + "");
                    strings.add(bean.getBarCode() + "");
                    strings.add(bean.getBookName() + "");
                    strings.add(bean.getCallNo() + "");
                    strings.add(bean.getShelfCode() + "");
                    strings.add(bean.getShelfName() + "");
                    return strings;
                }).collect(Collectors.toList());
            } else {
                collect = StreamSupport.stream(shelfWithBooks.get(key)).map((java8.util.function.Function<BookBean, List<String>>) bean -> {
                    ArrayList<String> strings = new ArrayList<>();
                    strings.add(bean.getTid() + "");
                    strings.add(bean.getBarCode() + "");
                    strings.add(bean.getBookName() + "");
                    strings.add(bean.getCallNo() + "");
                    strings.add(bean.getShelfCode() + "");
                    strings.add(bean.getShelfName() + "");
                    return strings;
                }).collect(java8.util.stream.Collectors.toList());
            }
            ExcelUtils.writeObjListToExcel(collect, filePath, context);
        }

    }
}
